////
/// Shared Utilities
/// Layout
////

/// Generate a selector chain to resolve draggable source layouts
/// @param {ArgList} $nth-children - Any number of numeric values
/// eg: (1, 2, 5, 7, 8, 9)
@mixin draggable-source-layout($block-name, $nth-children...) {
  $selector-chain: ();

  @each $child in $nth-children {
    $child-selector: unquote('.#{$block-name}:nth-child(#{$child})');
    $adjacent-clone-selector: unquote(
      '.#{$block-name}.draggable--original ~ .#{$block-name}:nth-child(#{$child + 1})'
    );

    $selector-chain: append($selector-chain, $child-selector, comma);
    $selector-chain: append($selector-chain, $adjacent-clone-selector, comma);
  }

  #{$selector-chain} {
    @content;
  }
}

// Styles for (un)locking the ability to scroll the document.
// Requires the `data-html-scroll` attribute on <html>.
// Toggling of the attribute value is handled via JS.
@mixin scroll-lock {
  &[data-scroll-lock],
  &[data-scroll-lock] body {
    height: 100%;
  }

  &[data-scroll-lock='true'],
  &[data-scroll-lock='true'] body {
    overflow: hidden;
    max-height: 100vh;
  }
}

// Quick and easy max-width centered layout
@mixin centered-width($max-width: null) {
  margin-left: auto;
  margin-right: auto;
  max-width: $max-width;
}

// To be used on flex items. Resolves some common layout issues, such as
// text truncation not respecting padding or breaking out of container.
// https://css-tricks.com/flexbox-truncated-text/
@mixin flex-item-fix {
  min-width: 0;
  max-width: 100%;
}

// Center any element, any where, any time
@mixin flex-center($full-height: false) {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  text-align: center;

  @if $full-height {
    height: 100vh;
  }
}

// Toggle visibility + opacity
// @param {String} $state - Switch visibility `on` or `off`.
@mixin visible($isVisible: true) {
  @if $isVisible {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
  } @else {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }
}

// Remove item from layout, but leave visible to screenreaders
@mixin visually-hidden {
  clip: rect(0 0 0 0);
  position: absolute;
  overflow: hidden;
  margin: -0.1rem;
  padding: 0;
  width: 0.1rem;
  height: 0.1rem;
  border: 0;
}

// Set an element to cover its closest relatively positioned parent.
// @param {String} $position (optional) - The position value you wish to use.
// @param {Number} $z-index (optional) - Allows specifying a `z-index`
@mixin position-cover($position: absolute, $z-index: auto) {
  $positions-data: (static relative absolute fixed sticky);

  @if not index($positions-data, $position) {
    @error 'Position value `#{$position}` not found. Available positions: #{available-names($positions-data)}';
  }

  // can I specify it being unitless?
  @if type-of($z-index) == number {
    z-index: $z-index;
  }

  @if $position == 'static' {
    position: static;
    top: auto;
    right: auto;
    bottom: auto;
    left: auto;
    margin: 0;
  } @else {
    position: $position;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
  }
}

// Private mixin - used by `aspect-ratio()`
// @param {Number} $padding - Value to be used for padding-top.
@mixin _aspect-ratio-padding-top($padding: 0%) {
  padding-top: $padding;
  width: 100%;
  height: 0;
}

// Flexible element that retains its aspect-ratio
// @param {Number} $width - Unitless ratio value used to represent width.
// @param {Number} $height - Unitless ratio value used to represent height.
// @param {Boolean} $psuedo (optional) - If you want the sizing to be managed by a ::before element.
// ...elaborate on this explaination - what benefits does this provide?
@mixin aspect-ratio($width, $height, $pseudo: false) {
  // I think this conditional is broken
  @if $width != unitless($width) or $height != unitless($height) {
    @error 'You did not provide unitless numbers for `$width` and `$height`.';
  }

  $ratio-percentage: ($height / $width) * 100%;
  position: relative;
  overflow: hidden;

  @if $pseudo {
    &::before {
      @include _aspect-ratio-padding-top($ratio-percentage);
      content: '';
      display: block;
    }

    // selector will not include pseudo elements
    > * {
      @include cover(absolute);
    }
  } @else {
    @include _aspect-ratio-padding-top($ratio-percentage);
  }
}

// Clear height for floated children
// To be applied to a container
@mixin clearfix {
  &::after {
    content: '';
    display: table;
    clear: both;
  }
}

// Reset the `clearfix` style
// Often used within a `@supports` block
@mixin clearfix-reset {
  &::after {
    content: none;
    display: none;
    clear: none;
  }
}
